#include "tcp_server.h"
#include "address.h"
#include "log.h"
#include "socket.h"
#include <cerrno>
#include <cstdint>
#include <cstring>
#include <vector>

const uint64_t g_tcp_server_read_timeout = 60 * 1000 * 2;  //2分钟

TcpServer::TcpServer(IOManager* worker
            ,IOManager* io_woker
            ,IOManager* accept_worker)
:m_worker(worker)
,m_ioWorker(io_woker)
,m_acceptWorker(accept_worker)
,m_recvTimeout(g_tcp_server_read_timeout)
,m_name("framework/1.0.0")
{
}

TcpServer::~TcpServer()
{
    for(auto& t: m_socks)
    {
        t->close();
    }
    m_socks.clear();
}



//绑定地址
bool TcpServer::bind(Address::ptr addr, bool ssl)
{
    std::vector<Address::ptr> addrs;
    addrs.emplace_back(addr);
    std::vector<Address::ptr> fails;
    return this->bind(addrs, fails, ssl);
}


//绑定地址数组
bool TcpServer::bind(const std::vector<Address::ptr>& addrs
                    ,std::vector<Address::ptr>& fails
                    ,bool ssl)
{
    m_ssl = ssl; 
    for(auto& addr:addrs)
    {
        Socket::ptr sock = ssl ? SSLSocket::CreateTCP(addr) : Socket::CreateTCP(addr);
        if(!sock->bind(addr))
        {
            log_error("bind fail errno:{}, errstr:{}, addr:{}",
                errno, strerror(errno), addr->toString());
            fails.emplace_back(addr);
            continue;
        }
        if(!sock->listen())
        {
            log_error("listen fail errno:{}, errstr:{}, addr:{}",
                errno, strerror(errno), addr->toString());
            fails.emplace_back(addr);
            continue;
        }
        m_socks.emplace_back(sock);
    }

    //如果有绑定或者监听失败的地址
    if(!fails.empty())
    {
        m_socks.clear();
        return false;
    }

    for(auto& t: m_socks)
    {
        log_info("type:{}, name:{}, ssl:{}, server bind success:{}",
            m_type, m_name, ssl, t->toString());
    }

    return true;
}


bool TcpServer::loadCertificates(const std::string& cert_file, const std::string& key_file)
{
    return false;
}

//开始接收连接
void TcpServer::startAccept(Socket::ptr sock)
{
    while(!m_isStop)
    {
        Socket::ptr client = sock->accept();
        if(client)
        {
            client->setRecvTimeout(m_recvTimeout);
            m_ioWorker->schedule(std::bind(&TcpServer::handleClient, shared_from_this(), client));
        }
        else
        {
            log_error("accept error, errno:{}, errstr:{}", errno, strerror(errno));
        }
    }
}


//启动服务(启动accept)
bool TcpServer::start()
{
    if(!m_isStop)
    {
        return true;
    }

    m_isStop = false;
    for(auto& sock: m_socks)
    {
        m_acceptWorker->schedule(std::bind(&TcpServer::startAccept, shared_from_this(), sock));
    }
    return true;
}

//停止服务
void TcpServer::stop()
{
    m_isStop = true;
    auto self = shared_from_this();

    //添加协程，取消sock上的所有事件并关闭sock
    m_acceptWorker->schedule([self](){
        for(auto& sock : self->m_socks)
        {
            sock->cancelAll();
            sock->close();
        }
        self->m_socks.clear();
    });
}


//设置TcpServerConf
void TcpServer::setConf(const TcpServerConf& v)
{
    m_conf.reset(new TcpServerConf(v));
}

std::string TcpServer::toString(const std::string& prefix)
{
    return prefix;
}



//客户端连接成功的回调函数  处理新连接的Socket类
void TcpServer::handleClient(Socket::ptr client)
{
    log_info("handleClient:{}", client->toString());
}